<!--
Copyright 2017 Google Inc. All Rights Reserved. Licensed under the Apache
License, Version 2.0 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or
agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Custom Elements Everywhere</title>
  <meta name="description" content="Making sure frameworks and custom elements can be BFFs 🍻">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Schema.org markup for Google+ -->
  <meta itemprop="name" content="Custom Elements Everywhere">
  <meta itemprop="description" content="Making sure frameworks and custom elements can be BFFs 🍻">
  <meta itemprop="image" content="https://custom-elements-everywhere.com/images/card.jpg">

  <!-- Twitter Card data -->
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@rob_dodson">
  <meta name="twitter:title" content="Custom Elements Everywhere">
  <meta name="twitter:description" content="Making sure frameworks and custom elements can be BFFs 🍻">
  <meta name="twitter:creator" content="@rob_dodson">
  <!-- Twitter summary card with large image must be at least 280x150px -->
  <meta name="twitter:image" content="https://custom-elements-everywhere.com/images/card.jpg">
  <meta name="twitter:image:alt" content="Making sure frameworks and custom elements can be BFFs 🍻">

  <link rel="icon" href="images/favicon.ico">
  <link rel="stylesheet" href="styles/bundle.css">

  <script>
    (function (i, s, o, g, r, a, m) {
      i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
        (i[r].q = i[r].q || []).push(arguments)
      }, i[r].l = 1 * new Date(); a = s.createElement(o),
        m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
    })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');

    ga('create', 'UA-105089944-1', 'auto');
    ga('send', 'pageview');

  </script>
</head>

<body>
  <section class="hero is-info is-large">
    <div class="hero-body">
      <div class="container">
        <div class="columns">
          <div class="column is-offset-1-tablet is-offset-0-widescreen">
            <h1 class="title is-1">
              Custom Elements Everywhere
            </h1>
            <h2 class="subtitle is-4">
              Making sure frameworks and custom elements can be BFFs
              <span class="cheers">🍻</span>
            </h2>
          </div>
        </div>
      </div>
    </div>
    {{>octocat}}
  </section>
  <section class="section">
    <div class="container">
      <div class="columns">
        <div class="column is-10-tablet is-offset-1-tablet is-7-widescreen is-offset-0-widescreen">
          <div class="content">
            <h2 class="title is-2">What's this?</h2>
            <p>
              Custom Elements are the lynchpin in the Web Components
              specifications. They give developers the ability to define their
              own HTML elements. When coupled with Shadow DOM, Custom Elements
              should be able to work in any application. But things don't always
              work seamlessly.
            </p>
            <p>
              This project runs a suite of tests against each framework to
              identify interoperability issues, and highlight potential fixes
              already implemented in other frameworks. If frameworks agree on
              how they will communicate with Custom Elements, it makes
              developers' jobs easier; they can author their elements to meet
              these expectations.
            </p>
            <p>
              Custom Elements and Shadow DOM don't come with a pre-defined set
              of best practices. The tests in this project are a best guess as
              to how things should work, but they're by no means final. This
              project is also about driving discussion and finding consensus, so
              don't be afraid to
              <a href="https://github.com/webcomponents/custom-elements-everywhere">open a GitHub issue</a>
              to discuss places where the tests could be improved. ✌️
            </p>
          </div>
        </div>
      </div>
    </div>
  </section>

  {{#each libraries}}
  <section class="section" id="{{name}}">
    {{#each aliases}}
    <span id="{{this}}"></span>
    {{/each}}
    <div class="container">
      <div class="columns is-flex-widescreen is-block-tablet">
        <div class="column is-10-tablet is-offset-1-tablet is-6-widescreen is-offset-0-widescreen">
          <div class="level">
            <div class="level-item has-text-centered">
              <div>
                <p class="heading">Library</p>
                <h3 class="title"><a href="{{repo.html_url}}">{{fullName}}</a> <span
                    class="library-version">{{results.libraryVersion}}</span></h3>
              </div>
            </div>
            <div class="level-item has-text-centered">
              <div>
                <p class="heading">Score</p>
                <p class="title">{{results.summary.score}}%</p>
              </div>
            </div>
            <div class="level-item has-text-centered">
              <div>
                <p class="heading">Basic Tests</p>
                <p class="title">{{results.summary.basicSupport.passed}}/{{results.summary.basicSupport.total}}</p>
                <div></div>

              </div>
            </div>
            <div class="level-item has-text-centered">
              <div>
                <p class="heading">Advanced Tests</p>
                <p class="title">{{results.summary.advancedSupport.passed}}/{{results.summary.advancedSupport.total}}
                </p>
              </div>
            </div>
          </div>
          <progress class="progress {{{warning-level results.summary.score}}}" value="{{results.summary.score}}"
            max="100">{{results.summary.score}}%</progress>
          <div class="content">
            {{{summary.content}}}
          </div>
          <div class="content">
            <a class="button is-info is-outlined" href="libraries/{{name}}/results/results.html">
              View the tests
            </a>
          </div>
        </div>
        <div class="column is-10-tablet is-offset-1-tablet is-5-widescreen is-offset-1-widescreen">
          <div class="box">
            <h4 class="title is-3">Related Issues</h4>
            {{#if issues}}
            {{#each issues}}
            <article class="media">
              <div class="media-content">
                <a href="{{link}}">
                  <div class="content">
                    <p>
                      <strong>{{title}}</strong>
                      <br>
                      <small>{{meta}}</small>
                    </p>
                  </div>
                </a>
              </div>
            </article>
            {{/each}}
            {{else}}
            <div class="has-text-centered">
              <img src="images/smiley.svg" alt="" width="256">
              <p class="title is-4 no-issues-caption">Yay! No open issues!</p>
            </div>
            {{/if}}
          </div>
        </div>
      </div>
    </div>
  </section>
  {{/each}}
  <section class="section">
    <div class="container">
      <div class="columns is-desktop">
        <div class="column is-10-tablet is-offset-1-tablet is-7-widescreen is-offset-0-widescreen">
          <div class="content">
            <h2 class="title is-2" id="faq">Frequently Asked Questions</h2>
            <div class="question">
              <h3 class="title is-4" id="faq-authoring-elements">
                What are these custom element things?
              </h3>
              <p>
                Custom elements are a new web standard which let developers
                create their own HTML Elements. Because they're based on web
                standards, these elements should work on any page. This means,
                you can write a component, like a datepicker, and share it
                everywhere.
              </p>
              <p>
                To learn more, check out the
                <a
                  href="https://developers.google.com/web/fundamentals/architecture/building-components/customelements">custom
                  elements primer</a>
                and
                <a
                  href="https://developers.google.com/web/fundamentals/architecture/building-components/best-practices">best
                  practices guide</a>.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-authoring-elements">
                Are you testing that libraries let you author custom elements?
              </h3>
              <p>
                No. These tests just check that a library/framework supports the
                <em>usage</em> of custom elements. Essentially we're trying to
                answer the question: "If you're building an app in framework X,
                and you'd like to include a few custom elements on the page, are
                you going to have a bad time?"
              </p>
              <p>
                The tests check that the library/framework will let you do
                things like display a custom element, bind data to it, pass in
                children, and listen for events.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-counted-twice">
                Why is each test counted twice?
              </h3>
              <p>
                We run each test in Chrome and Firefox. These days they behave
                basically the same with web components but years ago when these
                tests were first written, Firefox didn't yet have native support
                for Web Components.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-libraries-scored">
                How are the libraries scored?
              </h3>
              <p>
                Each test has an associated weight, based on how critical it is.
                The final tally of pass/fails is combined with these weights to
                create a weighted average score.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-basic-advanced-different">
                How are basic and advanced tests different?
              </h3>
              <p>
                Basic tests cover things which are fundamental to a
                library/framework's ability to display a custom element. For
                example, can it display a custom element that contains shadow
                DOM? Can it handle setting attributes on the custom element? Can
                it listen for DOM events from the element? Failing any of these
                tests is a pretty critical issue.
              </p>
              <p>
                Advanced tests cover more opinionated framework features. For
                example, does the framework provide declarative syntax for
                listening to events with different casing styles (kebab-case,
                camelCase, etc). These are more like "nice to haves" that may
                improve the developer experience.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-polymer">
                I thought the whole point of Polymer was to write custom
                elements. Why doesn't it get a 100%?
              </h3>
              <p>
                Polymer supports a non-standard feature called declarative event
                binding, which lets you use attributes to wire up event
                listeners. E.g. <code>&lt;my-element
                on-foo="handleFoo"&gt;</code>. Because DOM events are just
                strings, there are no rules governing how they should be
                formatted or capitalized—"my-event" is just as reasonable as
                "myEvent" or "myevent". Even the web platform has a few examples
                of oddly cased events like <code>DOMContentLoaded</code>.
                Because Polymer's implementation of declarative event bindings
                relies on pulling the event name from the <code>on-*</code>
                attribute, and the HTML parser will <em>always lowercase
                  attribute names</em>, it is unable to listen for events with
                capital letters in their names.
              </p>
              <p>
                Since it is entirely possible to write a vanilla custom element
                that dispatches an event with a capital letter in its name, and
                because there is prior art in the platform that actually uses
                this technique for event names with acronyms ("DOM"), we feel it
                is important to test this.
              </p>
              <p>
                Libraries like Preact also fail these capitalization tests,
                which points to a possible best practice of always making event
                names lowercase. This is the style most DOM events already use:
                <code>mousedown, popstate, beforeunload</code>, etc.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-missing-feature">
                If a library is missing a feature, like declarative event or
                property bindings, does it automatically fail those tests?
              </h3>
              <p>
                Not necessarily. If a library omits a
                <strong>non-standard</strong> feature aimed at developer
                ergonomics, e.g. declarative event/property bindings, we would
                just omit those tests from the scoring process.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-tests-for-library">
                Why don't you have tests for _____ library?
              </h3>
              <p>
                We'd like to have as much test coverage as possible, but it's
                a fair bit of work building each test suite (especially because
                we are not experts in every library). If a framework or library
                is not represented it's just because we haven't had a chance to
                write tests for it yet.
              </p>
            </div>
            <div class="question">
              <h3 class="title is-4" id="faq-accept-prs">
                I want to write some tests for _____ library. Do you accept pull
                requests?
              </h3>
              <p>
                Yes! In fact, >50% of the tests on this site are from external
                contributors.
              </p>
              <p>
                If you'd like to contribute, please first
                <a href="https://github.com/webcomponents/custom-elements-everywhere/issues">open an issue</a>
                saying you'd like to write some tests for a specific
                library/framework. This helps ensure that there's not more than
                one person writing tests for the same library.
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </section>

  <section class="hero is-info">
    <div class="hero-body">
      <p class="has-text-centered">
        <strong>Custom Elements Everywhere</strong> by <a href="https://twitter.com/rob_dodson">Rob Dodson</a>.
        Licensed under <strong><a
            href="https://github.com/webcomponents/custom-elements-everywhere/blob/master/LICENSE">Apache
            2.0</a></strong>.
      </p>
      <div class="has-text-centered fork-me-footer">
        <a href="https://github.com/webcomponents/custom-elements-everywhere">
          <img width="24" src="/images/octocat-white.svg" alt="GitHub Octocat">
        </a>
      </div>
    </div>
  </section>
  <script>
    const prNum = window.location.pathname.match(/\/preview\/preview\/preview\/(\d+)/)?.[1];
    if (prNum != null) {
      const previewDiv = document.createElement('div');
      previewDiv.id = 'preview-warning';
      const span = document.createElement('span');
      span.textContent = `This is a preview of a pull request, the content is still under review. You can find the pull request at `;
      const previewLink = document.createElement('a');
      previewLink.href = `https://github.com/webcomponents/custom-elements-everywhere/pull/${prNum}`;
      previewLink.textContent = `PR #${prNum}`;
      span.appendChild(previewLink);
      previewDiv.appendChild(span);
      document.body.prepend(previewDiv);
    }
  </script>
</body>

</html>
